<?php

namespace backend\modules\supplier\models\form;

use Yii;
use yii\base\Model;
use \common\models\goods\Goods;
use \common\models\goods\GoodsGallery;
use \common\models\goods\GoodsAttrVal;
use \common\models\goods\GoodsInfo;
use \common\models\product\Product;
use common\models\product\ProductBuyMin;
use common\models\product\ProductPrices;
use \common\models\goods\GoodsAttr;

/**
 * 商品编辑表单页
 */
class GoodsForm extends Model {

    public $isNewRecord;
    public $modelName = '商品';
    public $id;
    public $name;
    public $category_id;
    public $goods_type;
    public $brand_id;
    public $is_on_sale;
    public $is_stock_disable;
    public $is_auto_sale_on;
    public $is_auto_sale_off;
    public $factory_id;
    public $desc;
    public $pack_unit;
    public $remark;
    public $gallery;
    public $products;
    public $class_id;
    public $sku;

    /**
     * @return array the validation rules.
     */
    public function rules() {
        return [
            [['name', 'category_id'], 'required'],
            [['category_id', 'goods_type', 'brand_id', 'is_on_sale', 'is_stock_disable', 'is_auto_sale_on', 'is_auto_sale_off', 'factory_id'], 'integer'],
            [['name', 'class_id'], 'string', 'max' => 50],
            [['remark'], 'string', 'max' => 45],
            [['pack_unit'], 'string', 'max' => 8],
            [['goods_type', 'brand_id', 'is_stock_disable', 'factory_id', 'isNewRecord'], 'default', 'value' => 0],
            [['is_auto_sale_off', 'is_auto_sale_on'], 'default', 'value' => 1],
        ];
    }

    public function init() {
        parent::init();
        $this->is_on_sale = 1;
        $this->is_stock_disable = 0;
        $this->is_auto_sale_off = 1;
        $this->is_auto_sale_on = 1;
        $this->products = [new Product];
        $this->gallery = [['id' => '', 'img' => ''], ['id' => '', 'img' => ''], ['id' => '', 'img' => ''], ['id' => '', 'img' => ''], ['id' => '', 'img' => '']];
        $this->sku = [];
    }

    /**
     * @return array customized attribute labels
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'name' => '商品名称',
            'category_id' => '所属类目',
            'goods_type' => '商品类型',
            'brand_id' => '所属品牌',
            'img' => '商品图片',
            'is_on_sale' => '销售状态',
            'remark' => '备注',
            'pack_unit' => '包装单位',
            'class_id' => '分类',
            'is_stock_disable' => '下单时，不检测商品库存',
            'is_auto_sale_on' => '有库存时，自动上架',
            'is_auto_sale_off' => '没有库存时，自动下架',
            'factory_id' => '所属厂家',
            'desc' => '商品描述',
            'products' => '货品列表',
        ];
    }

    public function load($data, $formName = null) {
        //检查数据有效性
        if (parent::load($data, $formName) == FALSE) {
            return false;
        }

        //保存描述
        if (isset($data['GoodsForm']['desc'])) {
            $this->desc = $data['GoodsForm']['desc'];
        }

        //导入相册
        $this->gallery = [];
        for ($i = 0; $i < 5; $i++) {
            $this->gallery[] = isset($data['GoodsForm']['gallery'][$i]) ? $data['GoodsForm']['gallery'][$i] : ['id' => '', 'img' => ''];
        }

        //如果是有规格的的商品，验证属性是否已选择
        $this->sku = [];
        if (intval($data['GoodsForm']['goods_type']) > 0) {
            if (!isset($data['GoodsForm']['sku']) || count($data['GoodsForm']['sku']) <= 0) {
                $this->addError('sku', '规格未选择！');
                return FALSE;
            }

            foreach ($data['GoodsForm']['sku'] as $attr_id => $items) {
                foreach ($items as $item) {
                    $this->sku[$attr_id][$item['val']] = $item;
                }
            }
        }

        //导入货品信息
        if (isset($data['GoodsForm']['products'])) {
            $this->products = [];
            foreach ($data['GoodsForm']['products'] as $product) {
                if (empty($product['sn'])) {
                    $this->addError('products', '货品编号为空！');
                    return FALSE;
                }
                if (empty($product['price_cost'])) {
                    $this->addError('products', '货品成本价为空！');
                    return FALSE;
                }
                if (empty($product['weight'])) {
                    $this->addError('products', '货品重量为空！');
                    return FALSE;
                }

                //验证货品编号唯一
                $where = 'supplier_id=:supplier_id and sn=:sn';
                $param = [':supplier_id' => Yii::$app->user->identity->supplier_id, ':sn' => $product['sn']];
                if (!empty($product['id'])) {
                    $where.=' and id!=:id';
                    $param[':id'] = $product['id'];
                }
                $count = Product::find()->where($where, $param)->count();

                if ($count > 0) {
                    $this->addError('products', '货品编号重复！');
                    return FALSE;
                }

                $this->products[] = $product;
            }
        }


        return true;
    }

    /**
     * Sends an email to the specified email address using the information collected by this model.
     * @param  string  $email the target email address
     * @return boolean whether the model passes validation
     */
    public function save() {
        if ($this->validate()) {
            $goods = intval($this->id) > 0 ? Goods::findOne($this->id) : new Goods;
            !$goods && $goods = new Goods;
            $goods->setAttributes([
                'name' => $this->name,
                'category_id' => $this->category_id,
                'goods_type' => $this->goods_type,
                'brand_id' => $this->brand_id,
                'is_on_sale' => $this->is_on_sale,
                'remark' => $this->remark,
                'supplier_id' => Yii::$app->user->identity->supplier_id,
                'pack_unit' => $this->pack_unit,
                'class_id' => $this->class_id,
                'price_retail' => !empty($this->products['prices']['type'][1]['prices'][0]) ? $this->products['prices']['type'][1]['prices'][0] : NULL,
                'price_mix' => !empty($this->products['prices']['type'][2]['prices'][0]) ? $this->products['prices']['type'][2]['prices'][0] : NULL,
                'price_pack' => !empty($this->products['prices']['type'][3]['prices'][0]) ? $this->products['prices']['type'][3]['prices'][0] : NULL,
                'is_stock_disable' => $this->is_stock_disable,
                'is_auto_sale_on' => $this->is_auto_sale_on,
                'is_auto_sale_off' => $this->is_auto_sale_off,
                'factory_id' => $this->factory_id,
            ]);

            if ($goods->save()) {
                $this->id = $goods->id;

                //保存扩展信息
                $goodsInfo = GoodsInfo::find(['goods_id' => $goods->id])->one();
                !$goodsInfo && $goodsInfo = new GoodsInfo;

                $goodsInfo->setAttributes([
                    'goods_id' => $goods->id,
                    'desc' => $this->desc,
                ]);
                $goodsInfo->save();

                //保存相册
                $ids = [];
                $i = 5;
                $k = 0;
                foreach ($this->gallery as $item) {
                    if (empty($item['img'])) {
                        continue;
                    }
                    $gallery = intval($item['id']) <= 0 ? new GoodsGallery : GoodsGallery::findOne($item['id']);
                    if ($gallery->img != $item['img']) {
                        $gallery->saveImg($item['img']);
                    }
                    $gallery->goods_id = $goods->id;
                    $gallery->sort = $i;
                    $gallery->save();

                    $this->gallery[$k]['id'] = $gallery->id;
                    $this->gallery[$k]['img'] = $gallery->img;
                    $ids[] = $gallery->id;
                    $k++;
                    $i--;
                }

                //删除无效相册图片
                $condition = empty($ids) ? 'goods_id=:goods_id' : ['and', 'goods_id = :goods_id', ['not in', 'id', $ids]];
                $others = GoodsGallery::find()->where($condition, [':goods_id' => $goods->id])->all();
                foreach ($others as $item) {
                    $item->delete();
                }

                //保存商品属性
                $skus = $ids = [];
                if (count($this->sku) > 0) {
                    foreach ($this->sku as $attrId => $item) {
                        $list = [];
                        $attr = GoodsAttr::findOne($attrId);

                        foreach ($item as $i => $item2) {
                            $attrVal = intval($item2['id']) <= 0 ? new GoodsAttrVal : GoodsAttrVal::findOne($item2['id']);
                            !$attrVal && $attrVal = new GoodsAttrVal;

                            $old = $attrVal->img_url;
                            if (empty($item2['img'])) {
                                $attrVal->img_url = '';
                            } else {
                                $attrVal->saveImg($item2['img']);
                            }

                            if (empty($item2['img']) || $attrVal->img_url != $old) {
                                @unlink(Yii::getAlias('@img') . "/" . $old);
                            }

                            $attrVal['goods_id'] = $goods->id;
                            $attrVal['attr_id'] = $attrId;
                            $attrVal['attr_value'] = $item2['val'];
                            $attrVal['aliases'] = $item2['aliases'];
                            $attrVal->save();

                            $list[] = [$attrVal->id, $attr->name, $item2['aliases']];
                            $ids[] = $attrVal->id;
                        }
                        $skus[] = $list;
                    }
                    //生成规格组合
                    $allSku = $this->combos($skus);
                }
                
                $condition = empty($ids) ? 'goods_id=:goods_id' : ['and', 'goods_id = :goods_id', ['not in', 'id', $ids]];
                $others = GoodsAttrVal::find()->where($condition, [':goods_id' => $goods->id])->all();
                foreach ($others as $item) {
                    $item->delete();
                }
                

                //保存货品
                $allProductIds = [];
                if ($this->goods_type <= 0) {
                    //单个货品
                    $product = Product::find(['goods_id' => $goods->id, 'goods_attr' => ''])->one();
                    !$product && $product = new Product;
                    $product->goods_id = $goods->id;

                    $this->products[0]['goods_attr'] = '';
                    $this->products[0]['goods_attr_str'] = '';
                    $this->products[0]['img'] = '';

                    $product = $this->saveProductInfo($product, $this->products[0]);
                    if ($product->save()) {
                        $this->saveProductPrice($product->id, $this->products[0]['type']);
                        $allProductIds[] = $product->id;
                    }
                } else {
                    //多个货品
                    $products = [];
                    foreach ($this->products as $item) {
                        $products[] = $item;
                    }

                    $i = 0;
                    foreach ($allSku as $sku) {
                        $attrValId = $attrValStr = $con = $con2 = '';
                        foreach ($sku as $sku) {
                            $attrValId.=$con . $sku[0];
                            $con = ',';
                            $attrValStr.=$con2 . $sku[1] . '：' . $sku[2];
                            $con2 = ' ';
                        }

                        $product = Product::findOne(['goods_id' => $goods->id, 'goods_attr' => $attrValId]);
                        !$product && $product = new Product;
                        $product->goods_id = $goods->id;

                        $products[$i]['goods_attr'] = $attrValId;
                        $products[$i]['goods_attr_str'] = $attrValStr;
                        $products[$i]['img'] = '';

                        $product = $this->saveProductInfo($product, $products[$i]);
                        if ($product->save()) {
                            $this->saveProductPrice($product->id, $products[$i]['type']);
                            $allProductIds[] = $product->id;
                        }
                        $i++;
                    }
                }

                //删除无效货品
                $condition = empty($allProductIds) ? 'goods_id=:goods_id' : ['and', 'goods_id = :goods_id', ['not in', 'id', $allProductIds]];
                $others = Product::find()->where($condition, [':goods_id' => $goods->id])->all();
                foreach ($others as $item) {
                    $item->delete();
                }
            }

            $goods->updatePrices();
            $goods->updateStock();

            return true;
        }
    }

    /**
     * 保存货品信息
     * @param type $product
     * @param type $info
     * @return type
     */
    private function saveProductInfo($product, $info) {
        $product->setAttributes([
            //'goods_id' => $info['goods_id'],
            'sn' => $info['sn'],
            'sn_purchase' => $info['sn_purchase'],
            'sn_intel' => $info['sn_intel'],
            'goods_attr' => $info['goods_attr'],
            'goods_attr_str' => $info['goods_attr_str'],
            'price_market' => $info['price_market'],
            'price_cost' => $info['price_cost'],
            'img' => $info['img'],
            'name_short' => $info['name_short'],
            //'is_buy_min_disable'=>$info['is_buy_min_disable'],
            //'is_buy_setp_disable'=>$info['is_buy_setp_disable'],
            'weight' => $info['weight'],
            'supplier_id' => Yii::$app->user->identity->supplier_id,
            'slot' => $info['slot'],
        ]);
        return $product;
    }

    /**
     * 保存货品起订量和价格梯度
     * @param type $productId
     * @param type $types
     */
    private function saveProductPrice($productId, $types) {
        $stepIds = [];
        $priceIds = [];
        //销售类型保存
        foreach ($types as $type => $item) {
            if (empty($item['step'])) {
                continue;
            }

            $min = empty($item['id']) ? new ProductBuyMin : ProductBuyMin::findOne($item['id']);
            !$min && $min = new ProductBuyMin;
            $min->setAttributes([
                'product_id' => $productId,
                'type' => $type,
                'min' => $item['prices'][0]['min'],
                'step' => $item['step'],
            ]);
            $min->save();
            $stepIds[] = $min->id;

            foreach ($item['prices'] as $p) {
                if (empty($p['min'])) {
                    continue;
                }

                $price = empty($p['id']) ? new ProductPrices : ProductPrices::findOne($p['id']);
                !$price && $price = new ProductPrices;
                $price->setAttributes([
                    'product_id' => $productId,
                    'type' => $type,
                    'number' => $p['min'],
                    'price' => $p['price'],
                ]);
                $price->save();
                $priceIds[] = $price->id;
            }
        }

        //删除无效的起订量和价格梯度
        $condition = empty($stepIds) ? 'product_id=:product_id' : ['and', 'product_id = :product_id', ['not in', 'id', $stepIds]];
        ProductBuyMin::deleteAll($condition, [':product_id' => $productId]);

        $condition = empty($priceIds) ? 'product_id=:product_id' : ['and', 'product_id = :product_id', ['not in', 'id', $priceIds]];
        ProductPrices::deleteAll($condition, [':product_id' => $productId]);
    }

    private function combos($data, &$all = array(), $group = array(), $val = null, $i = 0) {
        if (isset($val)) {
            array_push($group, $val);
        }

        if ($i >= count($data)) {
            array_push($all, $group);
        } else {
            foreach ($data[$i] as $v) {
                $this->combos($data, $all, $group, $v, $i + 1);
            }
        }

        return $all;
    }

    public function getInfo() {
        if (intval($this->id) <= 0) {
            return FALSE;
        }

        $goods = Goods::findOne($this->id);
        if (!$goods) {
            return false;
        }
        $this->setAttributes($goods->getAttributes());

        $goods->info && $this->desc = $goods->info->desc;

        $this->gallery = [];
        for ($i = 0; $i < 5; $i++) {
            if (isset($goods->gallery[$i])) {
                $this->gallery[] = ['id' => $goods->gallery[$i]->id, 'img' => $goods->gallery[$i]->img];
            } else {
                $this->gallery[] = ['id' => '', 'img' => ''];
            }
        }

        //加载货品
        $this->products = [];
        $p = $goods->products;
        if ($goods->products) {
            if ($this->goods_type > 0) {
                foreach ($p as $item) {
                    $this->products[$item->goods_attr] = $item;
                }
            } else {
                count($p) > 0 && $this->products[] = $p[0];
            }
        }

        if ($goods->sku) {
            foreach ($goods->sku as $item) {
                $this->sku[$item->attr_id][$item['attr_value']] = $item;
            }
        }
    }

}
